package com.link.base.base.wechat.service;

import com.link.base.base.wechat.model.WxCardSign;
import com.link.base.wechat.wxcard.service.WxCardInfoService;
import com.link.base.wechat.wxplatform.model.WxPlatform;
import com.link.base.wechat.wxplatform.service.WxPlatformService;
import com.link.base.wechat.wxtoken.service.WxTokenService;
import com.link.core.basic.service.BasicServiceException;
import com.link.core.basic.service.ServiceException;
import com.link.core.util.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.security.MessageDigest;
import java.util.*;

/**
 * 微信卡券签名
 *
 * @author KuangRuifeng
 * @date 2018年12月15日
 */
@Service
public class WxCardSignServiceImpl implements WxCardSignService {
    @Resource
    private WxPlatformService wxPlatformService;
    @Resource
    private WxTokenService wxTokenService;
    @Resource
    private WxCardInfoService wxCardInfoService;

    /**
     * 获取领取微信卡券需要的扩展字段
     *
     * @author KuangRuifeng
     * @date 2018年12月15日
     */
    @Override
    public List<WxCardSign> getCardExt(WxCardSign wxCardSign) throws Exception {
        List<WxCardSign> signList = wxCardSign.getSignList();
        for (WxCardSign wcs : signList) {
            String appid = getAppId(Long.valueOf(wcs.getWxPlatformId()));
            setExts(wcs, wxTokenService.getXcxJsTicketByAppId(appid).getJs_ticket());
        }
        return signList;
    }

    /**
     * 对添加微信卡券后返回的加密code进行解密
     *
     * @author KuangRuifeng
     * @date 2018年12月15日
     */
    @Override
    public List<WxCardSign> decryptCardCode(WxCardSign wxCardSign) throws Exception {
        List<WxCardSign> signList = wxCardSign.getSignList();
        for (WxCardSign wcs : signList) {
            // 调用解密API解密，然后放入code里
            String appid = this.getAppId(Long.valueOf(wcs.getWxPlatformId()));
            wcs.setCode(wxCardInfoService.codeDecrypt(appid, wcs.getEncryptCode()));
        }
        return signList;
    }

    /**
     * 获取微信服务号appid
     *
     * @author KuangRuifeng
     * @date 2018年12月15日
     * @param wxPlatformId 微信服务号id
     */
    @Override
    public String getAppId(Long wxPlatformId) throws Exception {
        // 参数为空时，返回默认值
        if (wxPlatformId == null) {
            return this.getAppId();
        }
        String appid;
        WxPlatform wxPlatform = new WxPlatform();
        wxPlatform.setId(wxPlatformId);
        wxPlatform = wxPlatformService.queryById(wxPlatform);
        if (null != wxPlatform) {
            appid = wxPlatform.getWx_app_id();
        } else {
            throw new ServiceException("WECHAT-012");
        }
        return appid;
    }

    /**
     * 重载getAppid方法，没有查询参数时默认查询主要的服务号
     *
     * @author KuangRuifeng
     * @date 2018年12月15日
     */
    @Override
    public String getAppId() throws Exception {
        String appid;
        WxPlatform wxPlatform = new WxPlatform();
        wxPlatform.setPrimary_flag("Y");
        wxPlatform.setWx_pp_type("服务号");
        List<WxPlatform> wxPlatforms = wxPlatformService.queryByExamplePage(wxPlatform);
        if (wxPlatforms != null && wxPlatforms.size() > 0) {
            wxPlatform = wxPlatforms.get(0);
            appid = wxPlatform.getWx_app_id();
        } else {
            throw new ServiceException("WECHAT-013");
        }
        return appid;
    }

    /**
     * 传入一个wxCardSign对象，给它添加签名属性
     *
     * @author KuangRuifeng
     * @date 2018年12月15日
     * @param wxCardSign 卡券签名参数
     * @throws Exception 异常
     */
    private static void setExts(WxCardSign wxCardSign, String apiTicket) throws Exception {
        String signature;
        String code = wxCardSign.getCode();
        String openid = wxCardSign.getOpedid();
        String cardId = wxCardSign.getCardId();
        String nonceStr = org.apache.commons.lang.RandomStringUtils.randomAlphanumeric(32);
        String timestamp = Long.toString(System.currentTimeMillis() / 1000);
        ArrayList<String> arrayList = new ArrayList<String>();
        // 自定义code
        if (StringUtils.isNotBlank(code)) {
            arrayList.add(code);
        }
        // 指定openid
        if (StringUtils.isNotBlank(openid)) {
            arrayList.add(openid);
        }
        arrayList.add(apiTicket);
        arrayList.add(timestamp);
        arrayList.add(cardId);
        arrayList.add(nonceStr);
        String[] arr = new String[arrayList.size()];
        arr = arrayList.toArray(arr);
        Arrays.sort(arr);
        StringBuilder content = new StringBuilder();
        for (String str : arr) {
            content.append(str);
        }
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        byte[] digest = md.digest(content.toString().getBytes());
        signature = byteToStr(digest);
        wxCardSign.setTimestamp(timestamp);
        wxCardSign.setNonceStr(nonceStr);
        wxCardSign.setSignature(signature);
    }

    /**
     * byte转字符串
     *
     * @author KuangRuifeng
     * @date 2018年12月15日
     * @param byteArray byte数组
     */
    private static String byteToStr(byte[] byteArray) {
        StringBuilder stringBuilder = new StringBuilder();
        for (byte b : byteArray) {
            stringBuilder.append(byteToHexStr(b));
        }
        return stringBuilder.toString();
    }

    /**
     * 字节转16位字符串
     *
     * @author KuangRuifeng
     * @date 2018年12月15日
     * @param mByte
     */
    private static String byteToHexStr(byte mByte) {
        char[] digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        char[] tempArr = new char[2];
        tempArr[0] = digit[(mByte >>> 4) & 0X0F];
        tempArr[1] = digit[mByte & 0X0F];
        return new String(tempArr);
    }

    @Override
    public Map<String, String> getExtraData(WxCardSign wxCardSign) throws Exception {
        String appId = getAppid(wxCardSign.getWxPlatformId());
        return wxCardInfoService.getExtraData(appId, wxCardSign.getCardId(), wxCardSign.getOuterStr());
    }

    /**
     * 获取微信服务号appid
     *
     * @author KuangRuifeng
     * @date 2018年12月15日
     * @param wxPlatformId 微信服务号id
     */
    @Override
    public String getAppid(Long wxPlatformId) throws Exception {
        // 参数为空时，返回默认值
        if (null == wxPlatformId) {
            return this.getAppid();
        }
        String appid;
        WxPlatform wxPlatform = new WxPlatform();
        wxPlatform.setId(wxPlatformId);
        wxPlatform = wxPlatformService.queryById(wxPlatform);
        if (null != wxPlatform) {
            appid = wxPlatform.getWx_app_id();
        } else {
            throw new BasicServiceException("未找到id为" + wxPlatformId + "的服务号");
        }
        return appid;
    }

    /**
     * 重载getAppid方法，没有查询参数时默认查询主要的服务号
     *
     * @author KuangRuifeng
     * @date 2018年12月15日
     */
    @Override
    public String getAppid() throws Exception {
        String appid;
        WxPlatform wxPlatform = new WxPlatform();
        wxPlatform.setPrimary_flag("Y");
        wxPlatform.setWx_pp_type("服务号");
        List<WxPlatform> wxPlatforms = wxPlatformService.queryByExamplePage(wxPlatform);
        if (wxPlatforms != null && wxPlatforms.size() > 0) {
            wxPlatform = wxPlatforms.get(0);
            appid = wxPlatform.getWx_app_id();
        } else {
            throw new BasicServiceException("获取appId异常");
        }
        return appid;
    }
}
